package it.valeandre.omino.utils;

import it.valeandre.omino.BaseFragmentActivity;
import it.valeandre.omino.MainActivity;
import it.valeandre.omino.R;
import it.valeandre.omino.model.Team;
import it.valeandre.omino.model.TeamsList;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.Hashtable;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.graphics.Typeface;
import android.text.format.DateFormat;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
import android.widget.ImageView;


public final class Utils {

	private static Hashtable<String, Typeface> typefaces = new Hashtable<String, Typeface>();
	
	public static void log(String type, String tag, String content) {
		if (isLogEnabled()) {
			if (type.equals("e")) {
				Log.e(tag, content);
			} else if (type.equals("i")) {
				Log.i(tag, content);
			} else if (type.equals("d")) {
				Log.d(tag, content);
			} else if (type.equals("w")) {
				Log.w(tag, content);
			} else {
				throw new Error("Wrong log type!");
			}
		}
	}

    public static void setLogoByName(String teamName, ImageView logo, int dimensionId) {
        Map<String, Integer> map = null;
        switch (dimensionId) {
            case Maps.LOGOS_DIMENSION_MID_ID:
                map = Maps.TEAM_LOGO_MID_MAP;
                break;
            case Maps.LOGOS_DIMENSION_SMALL_ID:
                map = Maps.TEAM_LOGO_SMALL_MAP;
                break;
            default:
                break;
        }

        logo.setImageResource(R.drawable.palla_calcio);
        for(String keyTeam: map.keySet()) {
            if(teamName.contains(keyTeam)) {
                logo.setImageResource(map.get(keyTeam));
            }
        }
    }
	
	public static void log(String type, String content) {
		log(type, "OMINO", content);
	}
	
	public static void log(String content) {
		log("d", content);
	}
	
	public static boolean isLogEnabled() {
		return Config.BUILD_TYPE == Config.BUILD_TYPE_TEST;
	}

	public static String convertStreamToString(InputStream is) throws IOException {
		if (is != null) {
			Writer writer = new StringWriter();

			char[] buffer = new char[1024];
			try {
				Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
				int n;
				while ((n = reader.read(buffer)) != -1) {
					writer.write(buffer, 0, n);
				}
			} finally {
				is.close();
			}
			return writer.toString();
		} else {
			return "";
		}
	}
	
	public static String ellipsize(String text, int maxCharacters) {

		if (text.length() > maxCharacters) {
			text = text.substring(0, maxCharacters - 4) + "...";
		}

		return text;
	}
	
	private Utils() {

	}
	
	public static void saveToken(Context context, String token) {
		SharedPreferences prefs = context.getSharedPreferences(MainActivity.GCM_PREFERENCES,  Context.MODE_PRIVATE);
		Editor edit = prefs.edit();
		edit.putString(MainActivity.KEY_GCM_TOKEN, token);
		edit.commit();
	}
	
	public static String readRegisteredToken(Context context) {
		if (context != null) {
			SharedPreferences prefs = context.getSharedPreferences(MainActivity.GCM_PREFERENCES, Context.MODE_PRIVATE);
			String token = prefs.getString(MainActivity.KEY_GCM_TOKEN, null);
			return token;
		} else {
			return null;
		}
	}
	
	public static String readRankingLastDate(Context context) {
		if (context != null) {
			SharedPreferences prefs = context.getSharedPreferences(MainActivity.GCM_PREFERENCES, Context.MODE_PRIVATE);
			long dateInMilliseconds = prefs.getLong(MainActivity.KEY_RANKING_LAST_DATE, -1);
			if (dateInMilliseconds == -1) {
				return "non disponibile";
			} else {
				return DateFormat.format("dd/MM/yy hh:mm", dateInMilliseconds).toString();
			}
		} else {
			return "non disponibile";
		}
		
	}
	
	public static void saveShowDisclaimer(Context context, boolean showNextTime) {
		SharedPreferences prefs = context.getSharedPreferences(MainActivity.GCM_PREFERENCES,  Context.MODE_PRIVATE);
		Editor edit = prefs.edit();
		edit.putBoolean(BaseFragmentActivity.KEY_SHOW_DISCLAIMER, showNextTime);
		edit.commit();
	}
	
	public static boolean readShowDisclaimer(Context context) {
		if (context != null) {
			SharedPreferences prefs = context.getSharedPreferences(MainActivity.GCM_PREFERENCES, Context.MODE_PRIVATE);
			boolean show = prefs.getBoolean(MainActivity.KEY_SHOW_DISCLAIMER, true);
			return show;
		} else {
			return true;
		}
	}
	
	public static void saveRankingLastDate(Context context, long milliseconds) {
		SharedPreferences prefs = context.getSharedPreferences(MainActivity.GCM_PREFERENCES,  Context.MODE_PRIVATE);
		Editor edit = prefs.edit();
		edit.putLong(MainActivity.KEY_RANKING_LAST_DATE, milliseconds);
		edit.commit();
	}
	
//	public static String generateUniqueDeviceID(Context context) {
//		final TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
//
//	    final String tmDevice, tmSerial, androidId;
//	    tmDevice = "" + tm.getDeviceId();
//	    tmSerial = "" + tm.getSimSerialNumber();
//	    androidId = "" + android.provider.Settings.Secure.getString(context.getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);
//
//	    UUID deviceUuid = new UUID(androidId.hashCode(), ((long)tmDevice.hashCode() << 32) | tmSerial.hashCode());
//	    String deviceId = deviceUuid.toString();
//	    return deviceId;
//	}

	
	public static float getDisplayDensity(Activity context) {
		DisplayMetrics metrics = new DisplayMetrics();
		context.getWindowManager().getDefaultDisplay().getMetrics(metrics);
		return metrics.densityDpi;
	}
	
	public static int getDisplayWidth(Activity context) {
		DisplayMetrics metrics = new DisplayMetrics();
		context.getWindowManager().getDefaultDisplay().getMetrics(metrics);
		return metrics.widthPixels;
	}
	
	public Document XMLfromString(String v){

        Document doc = null;

        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        try {

            DocumentBuilder db = dbf.newDocumentBuilder();

            InputSource is = new InputSource();
            is.setCharacterStream(new StringReader(v));
            doc = db.parse(is); 

        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            System.out.println("Wrong XML file structure: " + e.getMessage());
            return null;
        } catch (IOException e) {
            e.printStackTrace();
        }

        return doc;

    }
	
	public static String convertDateToString(Date date, String format) {
		SimpleDateFormat dateFormat = new SimpleDateFormat(format);
		String ret = dateFormat.format(date);
		return ret;
	}
	
	public static String convertGmtStringToString(String stringDate, String inDateFormat, String outDateFormat, Locale locale) {
        String ret;
		Date date = convertGmtStringToDate(stringDate, inDateFormat, locale);
        SimpleDateFormat sdf = new SimpleDateFormat(outDateFormat);
        ret = sdf.format(date);
		return ret;
	}

    public static String convertGmtStringToString(String stringDate, String inDateFormat, Locale locale) {
        return convertGmtStringToString(stringDate, inDateFormat, ResBundle.DEFAULT_DATE_FORMAT, locale);
    }

    public static Date convertGmtStringToDate(String date, String dateFormat, Locale locale) {
//		Sat, 22 Dec 2012 10:37:14 GMT+01:00
//		String dateFormat  = "EEE, dd MMM yyyy HH:mm:ss z";
        Date ret;
        try {
            ret = new SimpleDateFormat(dateFormat, locale).parse(date);
        } catch (ParseException e) {
            ret = null;
            e.printStackTrace();
        }
        return ret;
    }
	
	public static Date convertGmtStringToDate(String date, SimpleDateFormat dateFormat) {
//		Sat, 22 Dec 2012 10:37:14 GMT+01:00
//		String dateFormat  = "EEE, dd MMM yyyy HH:mm:ss z";
		Date ret;
		try {
			ret = dateFormat.parse(date);
		} catch (ParseException e) {
			ret = null;
			e.printStackTrace();
		}
		return ret;
	}
	
	public static long fromGMTStringDateToMillisec(String gmtDate, SimpleDateFormat dateFormat) {
		Date date = convertGmtStringToDate(gmtDate, dateFormat);//"EEE, dd MMM yyyy HH:mm:ss z"
		return date.getTime();
	}
	
	public static long fromGMTStringDateToMillisec(String gmtDate, String dateFormat, Locale locale) {
		Date date = convertGmtStringToDate(gmtDate, dateFormat, locale);//"EEE, dd MMM yyyy HH:mm:ss z"
		return date.getTime();
	}
	
	public static String fromMillisecToStringGMT(Long millisec, String dateFormat, Locale locale) {
		SimpleDateFormat sdf = new SimpleDateFormat(dateFormat, locale);
		Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(millisec);
        
		return sdf.format(calendar.getTime());
	}
	
	public static String convertLocale(String gmtDate, Locale in, Locale out, String inDateFormat, String outDateFormat) {
		long dateLong = fromGMTStringDateToMillisec(gmtDate, inDateFormat, in);
		return fromMillisecToStringGMT(dateLong, outDateFormat, out);
	}
	
//	public static String convertLocale(String gmtDate, String inDateFormat, String outDateFormat) {
//		long dateLong = fromGMTStringDateToMillisec(gmtDate, inDateFormat);
//		return fromMillisecToStringGMT(dateLong, outDateFormat);
//	}
	
	public static List<Long> orderMillisecDates(Set<Long> dates) {
		List<Long> array = new ArrayList<Long>(dates);
		Collections.sort(array, new Comparator<Long>() {

			public int compare(Long lhs, Long rhs) {
				if (lhs > rhs)
					return -1;
				else if (lhs < rhs)
					return 1;
				else
					return 0;
			}
		});
		
		return array;
	}
	
	public static String formatOminoPagerDate(String date) {
//		Set<String> weekset = Utils.DATE_WEEK_DAYS_MAP_IT.keySet();
//		for(String wday: weekset) {
//			if(date.contains(wday)) {
//				date = date.replace(wday, Utils.DATE_WEEK_DAYS_MAP_IT.get(wday));
//			}
//		}
//		
//		Set<String> monthset = Utils.DATE_MONTHS_MAP_IT.keySet();
//		for(String month: monthset) {
//			if(date.contains(month)) {
//				date = date.replace(month, Utils.DATE_MONTHS_MAP_IT.get(month));
//			}
//		}
		
		
//		String timeregex = "[0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}";
//		date = date.replaceAll(timeregex, "");
		
		int end = date.indexOf("T");
		date = date.substring(0, end);
		Utils.log("DATE formatted group = " + date);
		return date.trim();
	}
	
	public static Typeface getTypeface(Context context, String name) {
		if (typefaces.containsKey(name)) {
			return typefaces.get(name);
		} else {
			Typeface typeface = Typeface.createFromAsset(context.getAssets(), name);
			typefaces.put(name, typeface);
			return typeface;
		}
	}

    public static float dipToPixels(Context context, float dipValue) {
        DisplayMetrics metrics = context.getResources().getDisplayMetrics();
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dipValue, metrics);
    }
    
    public static TeamsList get2014SerieATeams() {
    	ArrayList<Team> teamsArray = new ArrayList<Team>();
    	for(String teamName: Maps.TEAM_LOGO_MID_MAP.keySet()) {
    		if (!teamName.equalsIgnoreCase("Hellas")) {
				Team t = new Team();
				t.setValue(teamName);
				teamsArray.add(t);
			}
    	}
    	TeamsList tList = new TeamsList();
    	tList.setTeams(teamsArray);
    	return tList;
    }
	
}